//
//  InMemoryFileSystem.h
//  FuseSQLite
//
//  Created by Admin on 6/8/14.
//  Copyright (c) 2014 Admin. All rights reserved.
//

#ifndef IN_MEMORY_FILE_SYSTEM_H_
#define IN_MEMORY_FILE_SYSTEM_H_

#include "InMemoryFile.h"

#include <vector>
#include <string>
#include <memory>

#include <sys/stat.h>

struct FileInfo
{
    FileInfo()
    : stat({0})
    {}
    
    std::string name;
    struct stat stat;
    
};

struct FsTreeNode
{
    FsTreeNode(const char* aName, bool isDirectory)
    : name(aName)
    , stat({0})
    {
        stat.st_mode = 0777 | (isDirectory ? S_IFDIR : S_IFREG);
        stat.st_nlink = 1;
        
        if (!isDirectory)
            fileData.reset(new std::vector<char>);
    }
    
    std::string name;
    struct stat stat;
    
    std::vector<std::shared_ptr<FsTreeNode>> children;
    
    std::unique_ptr<std::vector<char>> fileData;
};

class InMemoryFileSystem
{
public:
    InMemoryFileSystem();
    
    bool createDirectory(const char* path, mode_t mode);
    bool remove(const char* path);
    bool renameDirectory(const char* path, const char* newName);
    bool readDirectory(const char* directoryPath, std::vector<FileInfo>* children);
    bool getAttributes(const char* path, struct stat* stat);
    
    bool createFile(const char* filePath, std::unique_ptr<InMemoryFile>* file);
    bool openFile(const char* filePath, std::unique_ptr<InMemoryFile>* file);
    bool truncateFile(const char* filePath, size_t newSize);
    
private:
    FsTreeNode* getParentNode(const std::vector<std::string>& pathComponents);
    FsTreeNode* getNode(const std::vector<std::string>& pathComponents);
    
private:
    FsTreeNode m_root;
};

#endif //IN_MEMORY_FILE_SYSTEM_H_
